package com.ihrm.company.service;


import com.ihrm.common.utils.IdWorker;
import com.ihrm.company.dao.CompanyDao;
import com.ihrm.domain.company.Company;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Optional;


/**
 * @知识概览
 *
 * // @Service 的作用
 * 在 Spring 应用中，@Service 注解的主要作用是：
 * 标识业务逻辑层：将一个类标记为服务层组件，表明它主要负责业务逻辑的处理。
 * 自动检测和注册：Spring 的组件扫描机制会自动检测带有 @Service 注解的类，
 * 并将其注册为一个 Bean，从而可以被 Spring 容器管理。
 * 依赖注入支持：服务层类可以方便地使用 Spring 的依赖注入（DI）功能，
 * 通过 @Autowired 注入其他 Bean（如数据访问层的 Repository 或其他服务
 */
// 这是操作 co_company 表的业务逻辑层
@Service
public class CompanyService {

    @Autowired
    private CompanyDao companyDao;
    /**
     * @这里必须要看 知识点 1
     */
    @Autowired
    private IdWorker idWorker;
    /**
     * 保存企业
     */
    public void saveCompany(Company companyc) {
        Company company = new Company();
        company=companyc;
        // 基本属性 根据 id 生成器 ihrm_company 包下的  utils IdWorker 生成
        String id = idWorker.nextId()+"";  // 这里由于数据库字段是字符串 所以 这里需要转换
        company.setId(id);
        if (company.getName()==null){
            company.setName("测试公司");
        }// 这个是为了防止测试时数据库字段为空，后续记得删除和调整
        // 默认参数
        company.setAuditState("0"); // 审核状态 0 未审核 1 已通过
        company.setState(1); // 0 未激活  1 激活
        companyDao.save(company);
    }

    /**
     * 更新企业
     *  1 参数 Company
     *  2 根据id查询企业对象
     *  3 设修改属性
     *  4 调用 dao 完成更新
     */
    public void updateCompany(Company company) {
        // 这里用的是 Optional 防止空指针异常
        Optional<Company> temp = companyDao.findById(company.getId());
        if (!temp.isPresent()) {
            throw new IllegalArgumentException("Company with ID " + company.getId() + " does not exist.");
        }
        Company existingCompany = company;
        existingCompany.setName(company.getName());
        existingCompany.setCompanyPhone(company.getCompanyPhone());
        companyDao.save(existingCompany);
    }

    /**
     * 删除企业
     */
    public void deleteCompany(String id) {
        companyDao.deleteById(id);
    }
    /**
     * 根据 id查询企业
     */
    public Company findCompanyById(String id) {
        return companyDao.findById(id).get();
    }

    /**
     * @必看知识点 2
     *  为什么返回 Iterable<T>？
     * 1.1 灵活性
     * Iterable<T> 是一个更通用的接口：它表示一个可以被迭代的对象，而不仅仅是 List。
     * 这意味着你可以返回任何实现了 Iterable 接口的集合类型，例如 List、Set、甚至是自定义的迭代器。
     * 支持多种数据源：在某些情况下，数据可能来自不同的数据源（如数据库、文件、网络等），
     * 返回 Iterable 可以让你更灵活地处理这些数据，而不需要将其强制转换为 List。
     * 1.2 性能优化
     * 延迟加载：返回 Iterable 可以实现延迟加载（Lazy Loading）。这意味着数据只有在实际迭代时才会被加载，
     * 从而避免了不必要的内存占用。这对于处理大量数据时尤其重要。
     * 流式处理：Iterable 可以与 Java 8 的 Stream API 结合使用，从而实现更高效的流式处理，
     * 而不需要一次性加载所有数据到内存中。
     * 2. 如何处理 Iterable<T>？
     * 虽然 Iterable<T> 提供了灵活性和性能优势，但在实际开发中，你可能更习惯使用 List<T>。
     * 以下是一些常见的处理方式：
     * 2.1 转换为 List<T>
     * 如果你需要将 Iterable<T> 转换为 List<T>，可以使用 Java 的流式操作：
     *          Iterable<Company> companies = companyDao.findAll();
     *          List<Company> companyList = StreamSupport.stream(companies.spliterator(), false)
     *                                          .collect(Collectors.toList());
     *
     *  为什么不是直接返回 List<T>？
     * 虽然 List<T> 是一种更常用的数据结构，但直接返回 List<T> 会有一些限制：
     * 内存占用：如果数据量很大，一次性加载到 List 中可能会占用大量内存。
     * 灵活性不足：List 是一种具体的集合类型，返回 List 会限制实现的灵活性，例如无法直接返回 Set 或其他自定义的迭代器。
     * 延迟加载：List 通常需要一次性加载所有数据，无法实现延迟加载，这在处理大量数据时可能会导致性能问题。
     */

    /**
     * 查询全部企业列表
     */
    public Iterable<Company> findAll() {
        return companyDao.findAll();
    }


}
